/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package eu.bopet.jocadv.gui;

import com.jogamp.opengl.util.gl2.GLUT;
import eu.bopet.jocadv.core.Element;
import eu.bopet.jocadv.core.datum.Axis;
import eu.bopet.jocadv.core.datum.CSys;
import eu.bopet.jocadv.core.datum.Plane;
import eu.bopet.jocadv.core.datum.Point;
import eu.bopet.jocadv.core.elements.Line;
import java.util.Iterator;
import java.util.List;
import javax.media.opengl.GL2;
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;

/**
 *
 * @author bocskapeter
 */
public class ElementRenderer {

    private final GLUT glut;

    /**
     *
     * @param glRenderer
     */
    public ElementRenderer(GLRenderer glRenderer) {
        glut = new GLUT();
    }

    public void renderElements(GL2 gl, List<Element> elementList, int glMode) {
        Element element;
        Iterator<Element> iterator = elementList.iterator();

        while (iterator.hasNext()) {
            element = iterator.next();            
            if (element instanceof Axis) {
                renderAxis(gl, (Axis) element , glMode);
            } else if (element instanceof Point) {
                renderPoint(gl, (Point) element, glMode);
            } else if (element instanceof CSys) {
                renderCSys(gl, (CSys) element, glMode);
            } else if (element instanceof Plane) {
                renderPlane(gl, (Plane) element, glMode);
            } else if (element instanceof Line) {
                renderLine(gl, (Line) element, glMode);
            }

        }

    }

    public void renderPoint(GL2 gl, Point point, int glMode) {
        if (glMode == GL2.GL_SELECT) {                
                gl.glLoadName((int)point.getId());
            }

        gl.glColor3d(0.3, 1.0, 0.3);

        gl.glBegin(GL2.GL_POINTS);
        {
            gl.glVertex3d(point.getPoint().getX(), point.getPoint().getY(), point.getPoint().getZ());
        }
        gl.glEnd();

        gl.glRasterPos3d(point.getPoint().getX(), point.getPoint().getY(), point.getPoint().getZ());
        glut.glutBitmapString(GLUT.BITMAP_HELVETICA_12, " " + point.getName());
    }

    public void renderAxis(GL2 gl, Axis axis, int glMode) {
        if (glMode == GL2.GL_SELECT) {                
                gl.glLoadName((int)axis.getId());
            }

        gl.glColor3d(0.7, 0.4, 0.4);
        gl.glEnable(GL2.GL_LINE_STIPPLE);
        //F18F is the line pattern "----   --   ----"
        gl.glLineStipple(1, (short) 0xF18F);

        gl.glBegin(GL2.GL_LINES);
        {
            gl.glVertex3d(axis.getLine()[0].getX(), axis.getLine()[0].getY(), axis.getLine()[0].getZ());
            gl.glVertex3d(axis.getLine()[1].getX(), axis.getLine()[1].getY(), axis.getLine()[1].getZ());
        }
        gl.glEnd();
        gl.glDisable(GL2.GL_LINE_STIPPLE);

        gl.glRasterPos3d(axis.getLine()[0].getX(), axis.getLine()[0].getY(), axis.getLine()[0].getZ());
        glut.glutBitmapString(GLUT.BITMAP_HELVETICA_12, " " + axis.getName());
    }

    public void renderCSys(GL2 gl, CSys cs, int glMode) {
        if (glMode == GL2.GL_SELECT) {                
                gl.glLoadName((int)cs.getId());
            }
        gl.glLineWidth(2);
        //display coorinate system        
        gl.glBegin(GL2.GL_LINES);
        {
            // x axis:
            gl.glColor3d(1.0, 0.0, 0.0);
            gl.glVertex3d(cs.getOrigin().getX(), cs.getOrigin().getY(), cs.getOrigin().getZ());
            gl.glVertex3d(cs.getOrigin().getX() + cs.getAxisX().getX(), cs.getOrigin().getY() + cs.getAxisX().getY(), cs.getOrigin().getZ() + cs.getAxisX().getZ());            
            // y axis:
            gl.glColor3d(0.0, 1.0, 0.0);
            gl.glVertex3d(cs.getOrigin().getX(), cs.getOrigin().getY(), cs.getOrigin().getZ());
            gl.glVertex3d(cs.getOrigin().getX() + cs.getAxisY().getX(), cs.getOrigin().getY() + cs.getAxisY().getY(), cs.getOrigin().getZ() + cs.getAxisY().getZ());
            // z axis:
            gl.glColor3d(0.0, 0.0, 1.0);
            gl.glVertex3d(cs.getOrigin().getX(), cs.getOrigin().getY(), cs.getOrigin().getZ());
            gl.glVertex3d(cs.getOrigin().getX() + cs.getAxisZ().getX(), cs.getOrigin().getY() + cs.getAxisZ().getY(), cs.getOrigin().getZ() + cs.getAxisZ().getZ());
        }
        gl.glEnd();
        gl.glLineWidth(1);
        gl.glRasterPos3d(cs.getOrigin().getX(), cs.getOrigin().getY(), cs.getOrigin().getZ());        
        glut.glutBitmapString(GLUT.BITMAP_HELVETICA_12, "             |" + cs.getName());
    }

    private void renderPlane(GL2 gl, Plane plane, int glMode) {
        if (glMode == GL2.GL_SELECT) {                
                gl.glLoadName((int)plane.getId());
            }

        gl.glColor3d(0.6, 0.6, 0.2);
        gl.glBegin(GL2.GL_LINE_LOOP);
        for (Vector3D rectangle : plane.getRectangle()) {
            gl.glVertex3d(rectangle.getX(), rectangle.getY(), rectangle.getZ());
        }
        gl.glEnd();
    }

    private void renderLine(GL2 gl, Line line, int glMode) {
        if (glMode == GL2.GL_SELECT) {                
                gl.glLoadName((int)line.getId());
            }
        gl.glColor3d(1.0, 1.0, 1.0);
        gl.glBegin(GL2.GL_LINES);
        gl.glVertex3d(line.getEndPoint()[0].getX(), line.getEndPoint()[0].getY(), line.getEndPoint()[0].getZ());
        gl.glVertex3d(line.getEndPoint()[1].getX(), line.getEndPoint()[1].getY(), line.getEndPoint()[1].getZ());
        gl.glEnd();
    }
}
